Subscripts can be used either to retrieve the value of one or more array elements or to designate array elements to receive new values. The expression arr[12] denotes the value of the 13th element of arr (because subscripts start at 0), while the statement arr[12] = 5 stores the number 5 in the 13th element of arr without changing the other elements.
Elements of multidimensional arrays are specified by using one subscript for each dimension. IDL’s notational convention is that for generic arrays and images, the first subscript denotes the column and the second subscript denotes the row. In standard mathematical representation (linear algebra, for example), the convention is reversed: the first subscript denotes the row and the second subscript denotes the column.
If A is a 2-element by 3-element array (using [column, row] notation), the elements are stored in memory as follows:
|
|
Stored in Memory |
A0,0 |
A1,0 |
Lowest memory address |
A0,1 |
A1,1 |
. |
A0,2 |
A1,2 |
Highest memory address |
The elements are ordered in memory as: A0,0, A1,0, A0,1, A1,1, A0,2, A1,2. This ordering is like Fortran. It is the opposite of the order used by C/C++. For more information on how IDL arranges multidimensional data in memory, see Columns, Rows, and Array Majority. For a discussion of how the ordering of such data relates to IDL mathematics routines, see Manipulating Arrays.
Note: When comparing IDL’s memory layout to other languages, remember that those languages usually use a mathematical [row, column] notation for array dimensions, which is the reverse of the array notation used for the example above. See Columns, Rows, and Array Majority for more on comparing IDL’s array layout to that of other languages.
Arrays that contain image data are usually displayed in graphics displays with row zero at the bottom of the screen, matching the display’s coordinate system (although this order can be reversed by setting the system variable !ORDER to a nonzero value). Array data are printed to standard text output (such as the IDL output log or console window) with the first row on top.
Arrays with multiple dimensions are addressed by specifying a subscript expression for each dimension. A two-dimensional array with n columns and m rows, is addressed with a subscript of the form [i, j], where 0 ≤ i < n and 0 ≤ j < m. The first subscript, i, is the column index; the second subscript, j, is the row index. For example, the following statements select and print the element in the first column of the second row of array:
array = [[1, 2, 3], [4, 5, 6]]
PRINT, array[0,1]
IDL prints:
4
Elements of multidimensional arrays also can be specified using only one subscript, in which case the array is treated as a vector with the same number of points.
A0,0 A0,1
A0,1 A1,1
A0,2 A1,2
In the 2 by 3 element array, A, element A[2] is the same element as A[0, 1], and A[5] is the same element as A[1, 2].
If an attempt is made to reference a nonexistent element of an array using a scalar subscript (a subscript that is negative or larger than the size of the dimension minus 1), an error occurs and program execution stops.
Subscripts can be any type of vector or scalar expression. If a subscript expression is not integer, a signed integer copy is made and used to evaluate the subscript.
Note: When floating-point numbers are converted to longword integers, they are truncated, not rounded. Thus, specifying A[1.99] is the same as specifying A[1].
Note: Subscripts are converted to the signed integer type used for addressing memory for your system (for example, on a 32-bit architecture, subscripts are converted to signed 32-bit integers). Using subscripts that are outside of the range for that integer type may produce unexpected results.
When creating arrays, IDL eliminates all size 1, or “degenerate”, trailing dimensions. Thus, the statements
A = INTARR(10, 1)
HELP, A
print the following:
A INT = Array[10]
This removal of superfluous dimensions is usually convenient, but it can cause problems when attempting to write fully general procedures and functions. Therefore, IDL allows you to specify “extra” dimensions for an array as long as the extra dimensions are all zero.
For example, consider a vector defined as follows:
arr = INDGEN(10)
The following are all valid references to the sixth element of arr:
X = arr[5]
X = arr[5, 0]
X = arr[5, 0, 0, *, 0]
Thus, the automatic removal of degenerate trailing dimensions does not cause problems for routines that attempt to access the resulting array.
The REFORM function can be used to add degenerate trailing dimensions to an array if desired. For example, the following statements create a 10 element integer vector, and then alter the dimensions to be [10, 1]:
A = INTARR(10)
A = REFORM(A, 10, 1, /OVERWRITE)
Versions of IDL prior to version 5.0 used parentheses to indicate array subscripts. Function calls use parentheses in a visually identical way to specify argument lists. As a result, the IDL compiler was not able to distinguish between arrays and functions by looking at the statement syntax. For example, the IDL statement
value = fish(5)
could either set the variable value equal to the sixth element of an array named fish, or set value equal to the result of passing the argument 5 to a function called fish.
To determine if it is compiling an array subscript or a function call, IDL checks its internal table of known functions. If it finds a function name that matches the unknown element in the command (fish, in the above example), it calls that function with the argument specified. If IDL does not find a function with the correct name in its table of known functions, it assumes that the unknown element is an array, and attempts to return the value of the designated element of that array. This rule generally gives the desired result, but it can be fooled into the wrong choice under certain circumstances, much to the surprise of the unwary programmer.
For this reason, versions of IDL beginning with version 5.0 use square brackets rather than parentheses for array subscripting. An array subscripted in this way is unambiguously interpreted as an array under all circumstances. In IDL 5.0 and later:
value = fish[5]
sets value to the sixth element of an array named fish.
Due to the large amount of existing IDL code written in the older syntax, as well as the ingrained habits of thousands of IDL users, IDL continues to allow the old syntax to be used, subject to the ambiguity mentioned above. That is, while
value = fish[5]
is unambiguous,
value = fish(5)
is still subject to the same ambiguity—and rules—that applied in IDL versions prior to version 5.0.
Since the older syntax has been used widely, you should not be surprised to see it from time to time. However, square brackets are the preferred form, and should be used for new code.